import { Middleware } from "koa";
import { validateAddTaskParam } from "../utils/validate";
import { RuntimeError } from "../model/RuntimeErrorr";
import { buildTaskService } from "../service/BuildTaskService";
import { Result } from "../factory/Result";
import { ListTaskParam } from "../model/Task";
import { BuildTaskRecord } from "../model/TaskRecordDBSchema";
import { notEmpty } from "../utils/isEmpty";
import { taskScheduler } from "../factory/TaskScheduler";
import { buildTaskResultService } from "../service/BuildTaskResultService";

export const addTask: Middleware = async (ctx) => {
  const bodyData = ctx.request.body || {};
  // 数据校验
  const { valid, data, errorMsg } = validateAddTaskParam(bodyData);
  if (!valid) throw new RuntimeError(errorMsg);
  // 插入数据
  await buildTaskService.add(data);
  ctx.body = Result.success("记录添加成功");
  // 尝试触发notify
  taskScheduler.notify();
};

const queryTaskList = async (param: ListTaskParam, matchTaskId = false) => {
  const keys = Object.keys(param);
  let rslt: BuildTaskRecord[] = [];
  if (!keys.length) {
    rslt = await buildTaskService.list();
  } else {
    rslt = await buildTaskService.list((val) => {
      for (let key of keys) {
        const p = param[key as keyof ListTaskParam];
        switch (key as keyof ListTaskParam) {
          case "startDate":
          case "endDate":
            if (
              notEmpty(param.endDate) &&
              notEmpty(param.startDate) &&
              notEmpty(val.startTime) &&
              notEmpty(val.endTime)
            ) {
              return (
                val.startTime >= param.startDate && val.endTime <= param.endDate
              );
            }
            break;
          case "status":
            if (notEmpty(p)) {
              return val.status === p;
            }
            break;
          case "taskId":
            if (notEmpty(p)) {
              return val.taskId === p;
            }
            if (matchTaskId) return false;
            break;
          case "taskTitle":
            if (notEmpty(p)) {
              return val.taskTitle.includes(String(p));
            }
            return true;
          default:
            break;
        }
      }
      return false;
    });
  }
  return rslt;
};

export const listTask: Middleware = async (ctx) => {
  const param: ListTaskParam = ctx.request.body || {};
  // 直接查询
  const rslt = await queryTaskList(param);
  ctx.body = Result.success(
    rslt
      .sort((a, b) => {
        return b.createTime - a.createTime;
      })
      .map((v) => {
        const { taskId, taskTitle, taskDesc, status } = v;
        return { taskId, taskTitle, taskDesc, status };
      })
  );
};

export const getTaskDetail: Middleware = async (ctx) => {
  const param: ListTaskParam = ctx.request.body || {};
  // 直接查询
  const rslt = await queryTaskList({ taskId: param.taskId }, true);
  ctx.body = Result.success(rslt?.[0] || null);
};

export const clearAll: Middleware = async (ctx) => {
  if (taskScheduler.isWorking()) {
    ctx.body = Result.fail("清理失败, 还有任务正在运行");
    return;
  }
  await Promise.all([
    buildTaskService.clearAll(),
    buildTaskResultService.clearAll(),
  ]);
  ctx.body = Result.success("清理成功");
};

export const clearById: Middleware = async (ctx) => {
  const param: Pick<ListTaskParam, "taskId"> = ctx.request.body || {};
  if (!param?.taskId) {
    return;
  }

  if (taskScheduler.workingTask()?.taskId === param.taskId) {
    ctx.body = Result.fail("删除失败, 该任务正在运行");
    return;
  }

  await Promise.all([
    buildTaskService.deleteById(param.taskId),
    buildTaskResultService.deleteById(param.taskId),
  ]);
  ctx.body = Result.success("删除成功");
};
